package com.rainbow.autocode.utils;

import com.rainbow.autocode.entity.ColumnEntity;
import com.rainbow.autocode.entity.ColumnEnum;
import com.rainbow.autocode.entity.SqlDmlEntity;
import com.rainbow.autocode.entity.TableEntity;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.util.ObjectUtils;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 代码生成器   工具类
 *
 * @author 付为地
 * @email 1335157415@qq.com
 * @date 2016年12月19日 下午11:40:24
 */
public class GenUtils {

	public static List<String> getTemplates(boolean isFirst,boolean isFallBack,boolean fallBackType){
		List<String> templates = new ArrayList<String>();
		templates.add("controller.ftl");
		templates.add("service.ftl");
		templates.add("serviceImpl.ftl");
		templates.add("dao.ftl");
		templates.add("entity.ftl");
		templates.add("mapper.ftl");
		templates.add("controllerTest.ftl");
		templates.add("QueryReqDto.ftl");
		templates.add("storeReqDto.ftl");
		templates.add("storeEnum.ftl");
		templates.add("respDto.ftl");
		//存在多个表生成相同模板时，需要针对处理
		if(isFirst){
			templates.add("baseWebTest.ftl");
		}
		//熔断时,才会加载模板,采用sentinel模式熔断降级,废弃掉老的feign在api熔断的处理
		if(isFallBack) {
			templates.add("feignClient.ftl");
			//默认采用sentinel处理熔断降级逻辑
			if (fallBackType) {
				templates.add("degrade.ftl");
			//默认采用feign处理,需要在api单独处理熔断降级
			} else {
				templates.add("fallback.ftl");
				templates.add("fallbackFactory.ftl");
			}
		}
		/*templates.add("serviceTest.ftl");*/
		/*templates.add("list.html.ftl");
		templates.add("insert.html.ftl");
		templates.add("update.html.ftl");*/
		return templates;
	}

	/**
	 * 生成代码
	 * baseWebTest存在相同文件重复
	 * 多选时本处选择第一个表生成,
	 * 其他表直接移除baseWebTest模板
	 * isFallback是否熔断
	 */
	public static void generatorCode(freemarker.template.Configuration freemaker, Map<String, String> table,
                                     List<Map<String, String>> columns, ZipOutputStream zip, SqlDmlEntity dmlEntity, boolean isFirst, boolean isFallback,String tableAlias){
		//配置信息
		Configuration config = getConfig();
		boolean hasBigDecimal = false;
		boolean hasDate = false;
		//表信息
		TableEntity tableEntity = new TableEntity();
		tableEntity.setTableName(table.get("tableName"));
		tableEntity.setComments(table.get("tableComment"));
		//表名转换成Java类名
		String className = tableToJava(tableEntity.getTableName(), config.getString("tablePrefix"));
		//tableAlias让第一个字母大写
		if(StringUtils.isNotEmpty(tableAlias)){
			className=StringUtils.capitalize(filterJavaName(tableAlias));
			tableEntity.setPojo(className);
		}
		tableEntity.setClassName(className);
		tableEntity.setClassname(StringUtils.uncapitalize(className));

		//列信息
		List<ColumnEntity> columsList = new ArrayList<>();
		List<ColumnEntity> rowList = new ArrayList<>();
		List<ColumnEntity> enumList = new ArrayList<>();
		for(Map<String, String> column : columns){
			ColumnEntity columnEntity = new ColumnEntity();
			columnEntity.setColumnName(column.get("columnName"));
			//数据库列类型
			columnEntity.setDatatype(column.get("dataType"));
			//数据库列类型大写
			columnEntity.setDataType(getJdbcType(column.get("dataType")));
			columnEntity.setComments(column.get("columnComment"));
			columnEntity.setExtra(column.get("extra"));
			//最大长度
			columnEntity.setMaxLength(ObjectUtils.isEmpty(column.get("maxLength"))?0:Long.parseLong(String.valueOf(column.get("maxLength"))));
			if(Objects.equals("NO",column.get("nullAble").toString().toUpperCase())){
				columnEntity.setNullAble(true);
			}else{
				columnEntity.setNullAble(false);
			}
			//列位置
			columnEntity.setPosition(ObjectUtils.isEmpty(column.get("position"))?0:Long.parseLong(String.valueOf(column.get("position"))));
			//默认值
			if(StringUtils.isNotEmpty(column.get("defaultValue"))){
				String defaultValue=column.get("defaultValue");
				if(Objects.equals("BIT",getJdbcType(column.get("dataType")))){//Boolean特殊处理
					defaultValue="b'1'".equals(defaultValue)?"true":"false";
				}
				columnEntity.setDefaultValue(defaultValue);
			}
			//列名转换成Java属性名
			String attrName = columnToJava(columnEntity.getColumnName());
			columnEntity.setAttrName(attrName);
			columnEntity.setAttrname(StringUtils.uncapitalize(attrName));

			//列的数据类型，转换成Java类型
			String attrType = config.getString(columnEntity.getDatatype(), "unknowType");
			columnEntity.setAttrType(attrType);
			columnEntity.setPropType(getJavaTypeAbs(attrType));
			if (!hasBigDecimal && "BigDecimal".equals(attrType)) {
				hasBigDecimal = true;
			}
			if (!hasDate && Objects.equals("Date" ,attrType)) {
				hasDate = true;
			}
			//默认值是否在entity,respDto,reqDto实体类生成,非主键列
			if(!config.getBoolean("enableEntityDefault")){
				columnEntity.setDefaultValue(null);
			}
			//创建枚举
			ColumnEnum columnEnum=createColumnEnum(columnEntity.getAttrName(),columnEntity.getComments());
			if(ObjectUtils.isEmpty(columnEnum)){
				columnEntity.setHasEnum(false);
			}else{
				columnEntity.setHasEnum(true);
				columnEntity.setColumnEnum(columnEnum);
				columnEntity.setComments(rebuildColumns(columnEnum));
				columnEntity.setColumeEnumDict(columnEntity.getColumnName().toUpperCase());
				enumList.add(columnEntity);
			}
			//是否主键
			if("PRI".equalsIgnoreCase(column.get("columnKey")) && tableEntity.getPk() == null){
				tableEntity.setPk(columnEntity);
			}else{
				rowList.add(columnEntity);
			}
			columsList.add(columnEntity);

		}

		tableEntity.setColumns(columsList);
		tableEntity.setColRows(rowList);
		tableEntity.setEnumRows(enumList);

		//没主键，则第一个字段为主键
		if(tableEntity.getPk() == null){
			tableEntity.setPk(tableEntity.getColumns().get(0));
		}

		/*String mainPath = config.getString("mainPath" );*/
		String mainPath = dmlEntity.getMainPath();
		mainPath = StringUtils.isBlank(mainPath) ? "com.qdone" : mainPath;

		//封装模板数据
		Map<String, Object> map = new HashMap<>();
		map.put("tableName", tableEntity.getTableName());
		map.put("comments", tableEntity.getComments());
		map.put("pk", tableEntity.getPk());
		map.put("className", tableEntity.getClassName());
		map.put("classname", tableEntity.getClassname());
		map.put("pathName", tableEntity.getClassname().toLowerCase());
		map.put("columns", tableEntity.getColumns());
		map.put("hasBigDecimal", hasBigDecimal);
		map.put("hasDate", hasDate);
		map.put("mainPath", mainPath);
		map.put("package", dmlEntity.getPackageName());
		map.put("moduleName", dmlEntity.getModuleName());
		map.put("bottomName", dmlEntity.getBottomName());
		map.put("controllerName", dmlEntity.getControllerName());
		map.put("serviceName", dmlEntity.getServiceName());
		map.put("daoName", dmlEntity.getDaoName());
		map.put("entityName", dmlEntity.getEntityName());
		//动态sql是否采用like，针对字符串
		map.put("dynamicLikeEnable", dmlEntity.getDynamicLikeEnable());
		map.put("author", dmlEntity.getAuthor());
		map.put("email", dmlEntity.getEmail());
		/*map.put("author", config.getString("author"));
		map.put("email", config.getString("email"));*/
		//是否生成controller降级代码
		map.put("isFallBack", isFallback);
		//是否采用默认的springMVC模式feign契约
		/*map.put("feignDefault", config.getBoolean("enableFeignDefault"));*/
		map.put("feignDefault", dmlEntity.getEnableFeignDefault());
		//降级默认采用sentinel处理，否则采用feign在api里面处理降级
		/*map.put("fallBackDefault", config.getBoolean("enableFallBackDefault"));*/
		map.put("fallBackDefault", dmlEntity.getEnableFallBackDefault());
		/*	map.put("package", config.getString("package" ));
		map.put("moduleName", config.getString("moduleName" ));
		map.put("bottomName", config.getString("bottomName" ));*/
        //服务拆分之后，对应控制层和持久化层的服务名称
		/*map.put("moduleName", serviceArr[0]);
		map.put("bottomName", serviceArr[1]);*/
		//自定义实体类包名
	/*	map.put("controllerName", config.getString("controllerName" ));
		map.put("serviceName", config.getString("serviceName" ));
		map.put("daoName", config.getString("daoName" ));
		map.put("entityName", config.getString("entityName" ));
		//动态sql是否采用like，针对字符串
		map.put("dynamicLikeEnable", config.getBoolean("dynamicLikeEnable" ));
		map.put("author", config.getString("author"));
		map.put("email", config.getString("email"));*/
		map.put("datetime", DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN));
		//没有主键的列
		map.put("columnsGroup", tableEntity.getColRows());
		//含有枚举的列
		map.put("hasEnumColumns", CollectionUtils.isNotEmpty(tableEntity.getEnumRows()));
		map.put("enumColumns", tableEntity.getEnumRows());
		//含有统一字段处理
		List<String> pubColums = Arrays.asList(config.getString("commonColumns").split(";"));
		map.put("hasBaseColumns",hasBaseColumns(tableEntity.getColumns(),pubColums));
		map.put("diffColumns",excludeDiffColumns(tableEntity.getColumns(),pubColums));
		//mybatis-plus针对db实体类更新策略配置,默认非空才会更新
		map.put("operatorStrategy",config.getString("configOperatorStrategy","DEFAULT"));

		//获取模板列表
		/*List<String> templates = getTemplates(isFirst,isFallback,config.getBoolean("enableFallBackDefault"));*/
		List<String> templates = getTemplates(isFirst,isFallback,dmlEntity.getEnableFallBackDefault());
		for(String template : templates){
			//渲染模板
			try {
				Template templete=freemaker.getTemplate(template);
				//可以针对不同模板数据特殊处理
				//添加页面还有更新页面比较特殊，页面循环复杂这里直接自定义
				buildPageElements(template,map,tableEntity);
				String content = FreeMarkerTemplateUtils.processTemplateIntoString(templete, map);
				//添加到zip,name判断一下重复,只要重复不执行压缩
				//判断文件是否存在
				/*zip.putNextEntry(new ZipEntry(getFileName(template, tableEntity.getClassName(),tableEntity.getClassname(), dmlEntity.getPackageName(), dmlEntity.getModuleName(),map)));*/
				String fileName=getFileName(template, tableEntity.getClassName(),tableEntity.getClassname(), dmlEntity.getPackageName(), dmlEntity.getModuleName(),map);
				if(StringUtils.isNotEmpty(fileName)){
					zip.putNextEntry(new ZipEntry(fileName));
					IOUtils.write(content, zip, "UTF-8");
					zip.closeEntry();
				}
				/*IOUtils.closeQuietly(content);*/
			}catch (TemplateException e) {
				throw new RRException("渲染模板失败，表名：" + tableEntity.getTableName(), e);
			} catch (IOException e) {
				throw new RRException("渲染模板失败，表名：" + tableEntity.getTableName(), e);
			}
		}
	}


	/**
	 * 判断表的所以字段是否包含固定五个基类统一字段
	 * create_time	timestamp	0	0	-1	0	0	0	0		0	创建时间				0	0
	 * update_time	timestamp	0	0	-1	0	0	0	0		0	更新时间				0	0
	 * creator	varchar	64	0	-1	0	0	0	0		0	创建人	utf8	utf8_general_ci		0	0
	 * updater	varchar	64	0	-1	0	0	0	0		0	更新人	utf8	utf8_general_ci		0	0
	 * flag	bit	1	0	-1	0	0	0	0	0	0	数据删除标识				0	0
	 * @param columns
	 * @return
	 */
	public static Boolean hasBaseColumns(List<ColumnEntity> columns,List<String> pubColums){
		if(ObjectUtils.isEmpty(columns)||ObjectUtils.isEmpty(pubColums)){
			return false;
		}
		List<Boolean> allCheckList=new ArrayList<>();
		for (String common:pubColums) {
			String commonName = common.split("-")[0];
			String commonType = common.split("-")[1];
			Boolean hasColumn = columns.stream().anyMatch(t -> org.apache.commons.lang3.ObjectUtils.isNotEmpty(t)
					&& org.apache.commons.lang3.ObjectUtils.isNotEmpty(t.getColumnName())
					&& org.apache.commons.lang3.ObjectUtils.isNotEmpty(t.getAttrType())
					&& Objects.equals(t.getColumnName(), commonName) && Objects.equals(t.getAttrType(), commonType)
			);
			if (hasColumn) {
				allCheckList.add(true);
			}
		}
		return pubColums.size()==allCheckList.size();


	}

	/**
	 * 生成实体类的时候将相同实体类参数排除
	 * @param columns
	 * @return
	 */
	public static List<ColumnEntity> excludeDiffColumns(List<ColumnEntity> columns,List<String> pubColums){
		if(ObjectUtils.isEmpty(columns)||ObjectUtils.isEmpty(pubColums)){
			return columns;
		}
		Map<String, String> commonMap=new HashMap<>();
		for (String common : pubColums) {
			String commonName = common.split("-")[0];
			String commonType = common.split("-")[1];
			if(org.apache.commons.lang3.ObjectUtils.isNotEmpty(commonName)&&org.apache.commons.lang3.ObjectUtils.isNotEmpty(commonType)){
				commonMap.put(commonName,commonType);
			}
		}
		List<ColumnEntity> list=new ArrayList<>();
		for (ColumnEntity item:columns) {
			String commonType= MapUtils.getString(commonMap,item.getColumnName(),"");
			if(org.apache.commons.lang3.ObjectUtils.isNotEmpty(commonType)&&Objects.equals(item.getAttrType(), commonType)){
				continue;
			}else {
				list.add(item);
			}
		}
		return list;
	}

	/**
	 * 根据数据库类型
	 * 找到对应的jdbcType
	 * @param columnType
	 * @return jdbcType
	 */
	public static String getJdbcType(String columnType){
		String[] blobArr=new String[]{"TINYBLOB","BLOB","MEDIUMBLOB","LONGBLOB"};
		String[] intArr=new String[]{"INTEGER","INT"};
		String[] textArr=new String[]{"TEXT","MEDIUMTEXT","LONGTEXT"};
		String[] timeArr=new String[]{"TIMESTAMP","DATETIME"};
		String[] charArr=new String[]{"VARCHAR","TINYTEXT"};
		if(Arrays.asList(blobArr).contains(columnType.toUpperCase())){
			columnType="BLOB";
		}else if(Arrays.asList(intArr).contains(columnType.toUpperCase())){
			columnType="INTEGER";
		}else if(Arrays.asList(textArr).contains(columnType.toUpperCase())){
			columnType="LONGVARCHAR";
		}else if(Arrays.asList(timeArr).contains(columnType.toUpperCase())){
			columnType="TIMESTAMP";
		}else if(Arrays.asList(charArr).contains(columnType.toUpperCase())){
			columnType="VARCHAR";
		}
		return columnType.toUpperCase();
	}

	/**
	 * 针对页面的特殊组件拼接复杂这里直接匹配写死
	 * 目前只针对 insert，update特殊处理
	 * @param template
	 * @param map
	 * @return
	 */
	public static Map<String, Object> buildPageElements(String template, Map<String, Object> map,TableEntity tableEntity){
		String classname=tableEntity.getClassname();
		int type=0;//生成表格是否含value，0表示insert 1表示update
		//添加表格
		StringBuffer searchAreaParam = new StringBuffer(1024);
		/*绘制添加表格，默认每行2列*/
		ArrayList<ColumnEntity> arr= (ArrayList<ColumnEntity>) tableEntity.getColRows();
		ColumnEntity pk=tableEntity.getPk();
		if("insert.html.ftl".equals(template)){
			int rowCloumSize=2;//每行两列显示
			if(arr.size()%rowCloumSize==0){//刚好整数倍，分拨次生成多行
				for (int i = 0; i <arr.size()/rowCloumSize; i++) {//共计多少行，field分多少组执行
					createRow(searchAreaParam,arr.subList(i*rowCloumSize, (i+1)*rowCloumSize),type,classname);
				}
			} else {
				if (arr.size() / rowCloumSize == 0) {// 不够rowCloumSize列，直接全部字段生成一行
					createRow(searchAreaParam, arr,type,classname);
				} else {
					for (int i = 0; i < arr.size() / rowCloumSize + 1; i++) {// 不是整数倍，分拨次生成多行，最后一行直接生成
						if (i == arr.size() / rowCloumSize) {
							createRow(searchAreaParam, arr.subList(i * rowCloumSize, arr.size()),type,classname);
						} else {
							createRow(searchAreaParam, arr.subList(i * rowCloumSize, (i + 1) * rowCloumSize),type,classname);
						}
					}
				}
			}
			map.put("insertFormParam",searchAreaParam.toString());
		} else if("update.html.ftl".equals(template)){
			type=1;//更新
			int rowCloumSize=2;//每行两列显示
			if(arr.size()%rowCloumSize==0){//刚好整数倍，分拨次生成多行
				for (int i = 0; i <arr.size()/rowCloumSize; i++) {//共计多少行，field分多少组执行
					createRow(searchAreaParam,arr.subList(i*rowCloumSize, (i+1)*rowCloumSize),type,classname);
				}
			} else {
				if (arr.size() / rowCloumSize == 0) {// 不够rowCloumSize列，直接全部字段生成一行
					createRow(searchAreaParam, arr,type,classname);
				} else {
					for (int i = 0; i < arr.size() / rowCloumSize + 1; i++) {// 不是整数倍，分拨次生成多行，最后一行直接生成
						if (i == arr.size() / rowCloumSize) {
							createRow(searchAreaParam, arr.subList(i * rowCloumSize, arr.size()),type,classname);
						} else {
							createRow(searchAreaParam, arr.subList(i * rowCloumSize, (i + 1) * rowCloumSize),type,classname);
						}
					}
				}
			}
			map.put("updateFormParam",searchAreaParam.toString());
		}
		return map;
	}


	/**
	 * 获取数据库字段类型对应java的类型
	 * eg：varchar  String
	 * return java.lang.String
	 * @param atrrType
	 * @return
	 */
	public static String getJavaTypeAbs(String atrrType){
		String atrrTypeAbs="java.lang.String";
		if(StringUtils.isEmpty(atrrType)){
			return atrrTypeAbs;
		}
		if("Integer".equals(atrrType)){
			atrrTypeAbs="java.lang.Integer";
		}else if("Long".equals(atrrType)){
			atrrTypeAbs="java.lang.Long";
		}else if("Float".equals(atrrType)){
			atrrTypeAbs="java.lang.Float";
		}else if("Double".equals(atrrType)){
			atrrTypeAbs="java.lang.Double";
		}else if("BigDecimal".equals(atrrType)){
			atrrTypeAbs="java.math.BigDecimal";
		}else if("Boolean".equals(atrrType)){
			atrrTypeAbs="java.lang.Boolean";
		}else if("String".equals(atrrType)){
			atrrTypeAbs="java.lang.String";
		}else if("Date".equals(atrrType)){
			atrrTypeAbs="java.util.Date";
		}
		return  atrrTypeAbs;
	}

	/**
	 * 列名转换成Java属性名
	 */
	public static String filterJavaName(String javaName) {
		if(StringUtils.isNotBlank(javaName)&&javaName.indexOf("_")!=-1){
			return columnToJava(javaName);
		}
		return javaName;
	}

	/**
	 * 列名转换成Java属性名
	 */
	public static String columnToJava(String columnName) {
		return WordUtils.capitalizeFully(columnName, new char[]{'_'}).replace("_", "");
	}

	/**
	 * 表名转换成Java类名
	 */
	public static String tableToJava(String tableName, String tablePrefix) {
		if(StringUtils.isNotBlank(tablePrefix)){
			tableName = tableName.replace(tablePrefix, "");
		}
		return columnToJava(tableName);
	}

	/**
	 * 获取配置信息
	 */
	public static Configuration getConfig(){
		try {
			return new PropertiesConfiguration("generator.properties");
		} catch (ConfigurationException e) {
			throw new RRException("获取配置文件失败，", e);
		}
	}

	/**
	 * 获取文件名
	 */
	public static String getFileName(String template, String className, String classname, String packageName, String moduleName,Map<String, Object> param ) {
		//controller和service所在服务包名
		String packagePath = "main" + File.separator + "java" + File.separator;
		if (StringUtils.isNotBlank(packageName)) {
			packagePath += packageName.replace(".", File.separator) + File.separator + moduleName + File.separator;
		}
		//dao和mapper所在服务包名
		String basePackagePath = "main" + File.separator + "java" + File.separator;
		String bottomName=ObjectUtils.isEmpty(param.get("bottomName"))?packageName:param.get("bottomName").toString();
		if (StringUtils.isNotBlank(packageName)) {
			basePackagePath += packageName.replace(".", File.separator) + File.separator + bottomName + File.separator;
		}
		//controller和service所在服务包名
		if (template.contains("controller.ftl" )) {
			return packagePath + param.get("controllerName") + File.separator + className + "Controller.java";
		}
		if (template.contains("service.ftl" )) {
			return packagePath + param.get("serviceName") + File.separator + className + "Service.java";
		}
		if (template.contains("serviceImpl.ftl" )) {
			return packagePath + param.get("serviceName")+ File.separator +"impl" + File.separator + className + "ServiceImpl.java";
		}
		//dao和mapper所在服务包名
		if (template.contains("entity.ftl" )) {
			return basePackagePath + param.get("entityName") + File.separator + className + "Entity.java";
		}
		if (template.contains("dao.ftl" )) {
			return basePackagePath + param.get("daoName")+ File.separator + className + "Mapper.java";
		}
		if (template.contains("mapper.ftl" )) {
			return "main" + File.separator + "resources" + File.separator + "mapper"
					+ File.separator + className + "Mapper.xml";
		}
		//入参和出参实体类
		if (template.contains("QueryReqDto.ftl" )) {
			return basePackagePath + "dto"+ File.separator +"req" +File.separator+ className + "QueryReq.java";
		}
		if (template.contains("storeReqDto.ftl" )) {
			return basePackagePath + "dto"+ File.separator +"req" +File.separator+ className + "StoreReq.java";
		}
		if (template.contains("respDto.ftl" )) {
			return basePackagePath + "dto"+ File.separator+ "resp" +File.separator+className + "Resp.java";
		}
		//生成表的枚举类
		Boolean hasEnumColumns= Boolean.valueOf(Objects.toString(param.get("hasEnumColumns")));
		if (template.contains("storeEnum.ftl" )&&hasEnumColumns) {
			return basePackagePath + "enums"+ File.separator+ className + "Enum.java";
		}
		//是否生成controller降级代码
		Boolean isFallBack= Boolean.valueOf(Objects.toString(param.get("isFallBack")));
		if(isFallBack){
			if (template.contains("feignClient.ftl" )) {
				return basePackagePath + "feign"+ File.separator+ "remote"+ File.separator+ className + "Client.java";
			}
			Boolean fallBackDefault= Boolean.valueOf(param.get("fallBackDefault").toString());
			if(fallBackDefault){
				//采用sentinel模式熔断降级生成
				if (template.contains("degrade.ftl" )) {
					return basePackagePath + "degrade"+ File.separator+ className + "ClientDegrade.java";
				}
			}else{
				//采用feign模式熔断降级生成
				if (template.contains("fallback.ftl")) {
					return basePackagePath + "feign" + File.separator + "fallback" + File.separator + className + "ClientFallBack.java";
				}
				if (template.contains("fallbackFactory.ftl")) {
					return basePackagePath + "feign" + File.separator + "fallback" + File.separator + "factory" + File.separator + className + "ClientFallBackFactory.java";
				}
			}
		}
		/*if (template.contains("list.html.ftl" )) {
			return "main" + File.separator + "resources" + File.separator + "page" + File.separator
					+ "view" + File.separator + classname + File.separator + "select"+className + ".html";
		}
		if (template.contains("insert.html.ftl" )) {
			return "main" + File.separator + "resources" + File.separator + "page" + File.separator
					+ "view" + File.separator + classname + File.separator + "insert"+className + ".html";
		}
		if (template.contains("update.html.ftl" )) {
			return "main" + File.separator + "resources" + File.separator + "page" + File.separator
					+ "view" + File.separator + classname + File.separator + "update"+className + ".html";
		}*/
		//controller和service单元测试
		if (template.contains("baseWebTest.ftl" )) {
			return "test" + File.separator + "java" + File.separator + packageName+File.separator+moduleName+ File.separator + "BaseWebTest.java";
		}
		if (template.contains("controllerTest.ftl" )) {
			return "test" + File.separator + "java" + File.separator + packageName+File.separator+moduleName+File.separator+param.get("controllerName")
					+ File.separator + className + "ControllerTest.java";
		}
		return null;
	}
	/**
	 * 创建某行
	 */
	public static  String createRow(StringBuffer searchAreaParam,List<ColumnEntity> arr,int type,String classname){
		searchAreaParam.append("             <tr>\n");
		for (int i = 0; i < arr.size(); i++) {
			createOneProperty(searchAreaParam, arr.get(i),type,classname);
		}
		searchAreaParam.append("             </tr>\n");
		return searchAreaParam.toString();
	}
	/**
	 * 创建某列字段
	 * @param searchAreaParam
	 * @param field
	 * @return
	 * updateby 付为地 2017-07-04 添加表格字段的长度控制,针对数据库varchar比较长的字段做处理,生成textarea方式
	 *          数据库可为空的,默认全部都是非必填,不能为空这里全部都是必填
	 */
	public static  String createOneProperty(StringBuffer searchAreaParam,ColumnEntity field,int type,String classname){
		//form表单的标题
		searchAreaParam.append((new StringBuilder("                <th>")).append(field.getComments()).append("</th>\n").toString());
		String varStr="";
		String val="";
		if(type==1){
			varStr="value='<#if "+classname+"."+field.getAttrname()+" ??>${"+classname+"."+field.getAttrname()+"}</#if>'";
			val="<#if "+classname+"."+field.getAttrname()+" ??>${"+classname+"."+field.getAttrname()+"}</#if>";
		}
		//form表单的内容，生成对应easyui控件
		//不可为空
		if(field.getNullAble()){
			//日期类型
			if("Date".equals(field.getAttrType())){//日期类型
				if(type==1){//update
					varStr="value='<#if "+classname+"."+field.getAttrname()+" ??>${"+classname+"."+field.getAttrname()+"?string(\"yyyy-MM-dd HH:mm:ss\")}</#if>'";
				}
				searchAreaParam.append("                <td><input id='"+field.getAttrname()+"' "+varStr+"  name='"+field.getAttrname()+"' readonly='true' onclick=\"laydate({istime: true, format: 'YYYY-MM-DD hh:mm:ss'})\"/></td>\n");
			}
			//number类型
			else if("Integer".equals(field.getAttrType())||"double".equals(field.getAttrType())||"BigDecimal".equals(field.getAttrType())){
				searchAreaParam.append("                <td><input id='"+field.getAttrname()+"' "+varStr+" name='"+field.getAttrname()+"' class='required number'  /></td>\n ");
			}
			//字符串类型
			else{
				Long max=field.getMaxLength()==0?1:field.getMaxLength();
				//超过100生成textarea
				if(field.getMaxLength()>=100){
					if(type==1){//update
						searchAreaParam.append("                <td><textarea id='"+field.getAttrname()+"' "+varStr+" name='"+field.getAttrname()+"' class='{required:true,maxlength:"+max+"}' row='2'/>"+val+"</textarea></td>\n");
					}else{//insert
						searchAreaParam.append("                <td><textarea id='"+field.getAttrname()+"' "+varStr+" name='"+field.getAttrname()+"' class='{required:true,maxlength:"+max+"}' row='2'/></textarea></td>\n");
					}
				}
				else{
					searchAreaParam.append("                <td><input id='"+field.getAttrname()+"' "+varStr+" name='"+field.getAttrname()+"' class='{required:true,maxlength:"+max+"}'/></td>\n");
				}
			}
		}else{//可为空
			//日期类型
			if("Date".equals(field.getAttrType())){//日期类型
				if(type==1){//update
					varStr="value='<#if "+classname+"."+field.getAttrname()+" ??>${"+classname+"."+field.getAttrname()+"?string(\"yyyy-MM-dd HH:mm:ss\")}</#if>'";
				}
				searchAreaParam.append("                <td><input id='"+field.getAttrname()+"' "+varStr+" name='"+field.getAttrname()+"' readonly='true' onclick=\"laydate({istime: true, format: 'YYYY-MM-DD hh:mm:ss'})\"/></td>\n");
			}
			//number类型
			else if("Integer".equals(field.getAttrType())||"Float".equals(field.getAttrType())||"Double".equals(field.getAttrType())||"BigDecimal".equals(field.getAttrType())){
				searchAreaParam.append("                <td><input id='"+field.getAttrname()+"' "+varStr+"  name='"+field.getAttrname()+"'  /></td>\n ");
			}
			//字符串类型
			else{
				if(field.getMaxLength()>=100){//超过100生成textarea
					if(type==1){//update
						searchAreaParam.append("                <td><textarea id='"+field.getAttrname()+"' "+varStr+" name='"+field.getAttrname()+"'  row='2'/>"+val+"</textarea></td>\n");
					}else{
						searchAreaParam.append("                <td><textarea id='"+field.getAttrname()+"' "+varStr+" name='"+field.getAttrname()+"'  row='2'/></textarea></td>\n");
					}
				}else{
					searchAreaParam.append("                <td><input id='"+field.getAttrname()+"' "+varStr+" name='"+field.getAttrname()+"'/></td>\n");
				}
			}
		}
		return searchAreaParam.toString();
	}


	/**
	 * 根据表的备注
	 * 生成表字段
	 * 具体枚举类型
	 * 针对格式为
	 * eg: 投入方式:(back)0:后台导入;(pda)1:PDA补录
	 * @param name 枚举类名称
	 * @param commont 表的备注信息
	 * @return
	 */
	private static ColumnEnum createColumnEnum(String name,String commont){
		if(StringUtils.isNotEmpty(commont)&&commont.indexOf(":")!=-1){
			ColumnEnum columnEnum=new ColumnEnum();
			columnEnum.setName(name);
			columnEnum.setRemark(commont.substring(0,commont.indexOf(":")));
			Set<ColumnEnum.Item> items=new LinkedHashSet<>();
			String data=commont.substring(commont.indexOf(":")+1);
			if(data.indexOf(":")!=-1&&data.indexOf(";")!=-1&&data.indexOf("(")!=-1&&data.indexOf(")")!=-1){
				String[] arr=data.split(";");
				if(!ObjectUtils.isEmpty(arr)&&arr.length>0){
					for (int i = 0; i <arr.length ; i++) {
						String row=arr[i];
						if(StringUtils.isNotEmpty(row)&&row.indexOf(":")!=-1){
							String[] rowArr=row.split(":");
							if(!ObjectUtils.isEmpty(rowArr)&&rowArr.length>0){
								String first=rowArr[0];
								String enumName=first.substring(first.indexOf("(")+1,first.indexOf(")")).replaceAll(" ","").toUpperCase();
								String enumCode=first.substring(first.indexOf(")")+1).replaceAll(" ","");
								items.add(new ColumnEnum.Item(enumName,enumCode,rowArr[1].replaceAll(" ","")));
							}
						}
					}
				}
				columnEnum.setItem(items);
				return columnEnum;
			}
		}
		return null;
	}

	/**
	 * 重新渲染列备注
	 * 源备注：投入方式:(back)0:后台导入;(pda)1:PDA补录;(dpd)2:其他处理
	 * 最终备注:投入方式:0:后台导入;1:PDA补录;2:其他处理
	 * @return
	 */
	private static String rebuildColumns(ColumnEnum columnEnum){
		if(ObjectUtils.isEmpty(columnEnum)){
			return null;
		}
		String memo=columnEnum.getRemark()+":";
		Iterator it=columnEnum.getItem().iterator();
		while (it.hasNext()){
			ColumnEnum.Item item= (ColumnEnum.Item) it.next();
			memo+=item.getCode()+":"+item.getValue()+";";
		}
		memo=memo.substring(0,memo.lastIndexOf(";"));
		return memo;
	}
}
